#pragma once

#include <QtGui/QApplication>

#include <boostext/exception.hpp>
#include <services/provider.hpp>

#include "exports.hpp"




namespace QtUi
{
	/**
	 * The Application class is an enhancement of QApplication
	 * and simplifies the use of this framework. It automatically
	 * creates a ServiceProvider and fills it with most basic
	 * services and also handles & reports all kinds of exceptions.
	 */
	class QTUI_API Application
		: public QApplication
	{
		Q_OBJECT

	public:

		static Application* instance();

	public:

		/**
		 * Create a GuiApplication.
		 * Creates all necessary services and pushes them into
		 * the ServiceProvider.
		 */
		Application(int argc, char** argv);

		/**
		 * Destroy a GuiApplication.
		 */
		virtual ~Application();



		/**
		 * Direct access to the ServiceProvider of the Application.
		 * This function can only be used to retrieve services, but
		 * not to register new ones.
		 */
		services::provider::ptr serviceProvider() const;



		/**
		 * Loads the given translation file.
		 */
		void loadTranslation(const QString& fname);



		/**
		 * Called when a std::exception has been caught.
		 * The application will terminate after this function
		 * has been called, this cannot be changed.
		 *
		 * @param except   the std::exception that has been caught
		 */
		static void onException(const std::exception& except);

		/**
		 * Called when a boost_ext::exception has been caught.
		 * The application will terminate after this function
		 * has been called, this cannot be changed.
		 *
		 * @param except   the boost_ext::exception that has been caught
		 */
		static void onException(const boostext::exception& except);

	private:

		/**
		 * Reimplementation of the notify() function.
		 * Used to catch exceptions, thrown in the GUI
		 * thread.
		 * When an exception has been caught, it will be
		 * reported to the user and the application will
		 * exit.
		 * This function only catches boost_ext::exception and
		 * std::exception. All other (non c++) exceptions
		 * will be caught by the exception handler service.
		 */
		bool notify(QObject *receiver, QEvent *event);

	private:

		static Application* m_theApp;

	protected:

		services::provider::ptr   m_provider;

		QTranslator       m_translator;
	};
	///////////////////////////////////////////////////////////////////////////////////////////////
}
///////////////////////////////////////////////////////////////////////////////////////////////////
